const route = require('express').Router();
const cookieParser = require('cookie-parser');
const uid = require('uid-safe');
const Question = require('./db/Question');
const config = require('./config.json');
const wiki = config.wiki;
const Redis = require('ioredis');
const redis = new Redis(config.redis);
const Statistic = require('./db/Statistic');

const QUESTION_COUNT = config.api_config.default_question_size;

if (config.cors) {
  const originStringify = require('mycuo-pkgs/lib/originStringify')
  const cors = require('cors');
  app.use(cors({
    origin: originStringify(config.cors),
    credentials: true
  }));
}

route.use(
  cookieParser('video-wiki-qa'),
  function (req, res, next) {
    if (req.signedCookies.client) {
      req.client = req.signedCookies.client;
    } else {
      res.cookie('client', uid.sync(8), {
        domain: '.mycuo.com',
        signed: true, httpOnly: true, maxAge: 365*24*60*60*1000
      });
    }
    next();
  },
  function (req, res, next) {
    if (req.signedCookies._admin) {
      req.isAdmin = true;
    } else if (req.query.admin === 'jarvis:mycuoadmin') {
      req.isAdmin = true;
      res.cookie('_admin', '1', {
        domain: '.mycuo.com',
        signed: true, httpOnly: true, maxAge: 10*60*1000
      });
    }
    next();
  }
);

route.get('/question', function (req, res, next) {
  const count = req.query.count || QUESTION_COUNT;
  Question.find()
    .sort({count_answered: 1, random: Math.random() > .5 ? 1: -1})
    .limit(count)
    .select({_id: 0, id: 1, content: 1, 'answers.id': 1, 'answers.content': 1})
    .then(questions => {
      res.json({
        questions: questions.map(ques => {
          const {id, content, answers} = ques.toJSON({virtual: false});
          return {id, content, answers}
        })
      });
    })
    .catch(next)
});

route.get('/answer', function (req, res, next) {
  const question = Number(req.query.question);
  const answer = Number(req.query.answer);
  if (isNaN(question) || isNaN(answer))
    return res.status(400).json({message: 'invalid answer'});

  Question.findOne({id: question})
    .then(ques => {
      const correctAnswer = ques.answers.find(ans => ans.isCorrect);

      const isCorrect = correctAnswer.id === answer;
      res.json({isCorrect,  correctAnswer: correctAnswer.id});

      ques.count_answered +=1;
      if (isCorrect) ques.count_correct +=1;
      ques.save();
    })
    .catch(next)
});

route.post('/add', function (req, res, next) {
  if (!req.isAdmin || !req.body) return next();
  const question = req.body;
  if (!(question.answers instanceof Array))
    return res.status(400).json({message: 'invalid answers'});

  question.answers.forEach((ans, index) => ans.id = index +1);
  Question.find().sort({id: -1}).limit(1)
    .then(([last]) => {
      const id = last ? last.id +1 : 1;
      return new Question({
        id, ...question
      }).save()
    })
    .then(newQues => {
      res.json({
        success: true,
        id: newQues.id
      })
    })
    .catch(next)
});

route.post('/update', function (req, res, next) {
  if (!req.isAdmin || !req.body) return next();
  const {content, answers} = req.body;
  const question = {}

  if (content) question.content = content;
  if (answers) {
    answers.forEach((ans, index) => ans.id = index);
    question.answers = answers;
  };

  const id = Number(req.query.question);
  if (isNaN(id))
    return res.status(400).json({message: 'invalid question'});

  if (!content && !answers)
    return res.json({message: 'nothing to update'});

  Question.findOneAndUpdate({id}, question)
    .then(updated => {
      res.json({success: Boolean(updated)})
    })
    .catch(next)
});

route.get('/wiki', function (req, res, next) {
  res.json(wiki);
  redis.hget(req.client, 'get_wiki')
    .then(getWiki => {
      const now = Date.now();
      if (getWiki && now - getWiki > 3 * 60 * 1000) {
        redis.hset(req.client, 'get_wiki', now);

      }
    })
})


module.exports = route;

